import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.sql.*;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
import dbBean.DBConnectionManager;

class udpListener implements Runnable {

TreeMap cache=null;

udpListener(TreeMap treeMap) {
	cache=treeMap;
}

public void run() {
  DBConnectionManager connMgr=DBConnectionManager.getInstance();

  BASE64Encoder encoder=new BASE64Encoder();
  BASE64Decoder decoder=new BASE64Decoder();
  Connection con=null;

  int idUser, latitud, longitud, velocidad, rumbo, altitud;
  java.sql.Timestamp timestamp=null;
  String password=null;
  byte[] buf = new byte[256];
  byte[] header=new byte[20];
  DatagramSocket socket = null;
  byte[] bytes;
  boolean salir=false;

  MessageDigest md=null;
  byte[] key=new byte[16];
  SecretKeySpec sc=null;
  Cipher cipher=null;

  try {
  	cipher=Cipher.getInstance("AES/ECB/NoPadding");
  } catch (GeneralSecurityException e) {
	e.printStackTrace();
	salir=true;
  }

  try {
    socket = new DatagramSocket(5900);
  } catch (SocketException e) {
	e.printStackTrace();
	salir=true;
  }

  DatagramPacket packet = new DatagramPacket(buf, buf.length);

  SimpleDateFormat formater=new SimpleDateFormat("ddMMyyHHmmssSSS");

  while(!salir) {
    try {
	socket.receive(packet);
	
	System.arraycopy(buf, 0, header, 0, 20);

	con=connMgr.getConnection("mysql");
        PreparedStatement pstmt=con.prepareStatement("SELECT id, password FROM usuarios WHERE digest=?;");
	pstmt.setString(1, encoder.encode(header));
	ResultSet rs=pstmt.executeQuery();
	if(rs.next()) {
	    idUser=rs.getInt("id");
	    password=rs.getString("password");
	    rs.close();
	    pstmt.close();

            System.arraycopy(decoder.decodeBuffer(password),0,key,0,16);
            sc=new SecretKeySpec(key, "AES");
            cipher.init(Cipher.DECRYPT_MODE, sc);

	    bytes=cipher.doFinal(buf, 20, packet.getLength() - 20);

	    String pos=new String(bytes);
	    String[] datos=pos.split(";");

	    if((datos.length==5) || (datos.length==6)) {
	    	latitud=Integer.parseInt(datos[0]);
	    	longitud=Integer.parseInt(datos[1]);
	    	velocidad=Integer.parseInt(datos[2]);
	    	rumbo=Integer.parseInt(datos[3]);

		if(datos.length==6) {
	    		altitud=Integer.parseInt(datos[4]);
			timestamp=new java.sql.Timestamp(formater.parse(datos[5].trim()).getTime());
			int i=pos.lastIndexOf(';');
			cache.put(idUser, timestamp.toString()+";"+pos.substring(0, i));
		} else {
	    		altitud=Integer.parseInt(datos[4].trim());
			timestamp=new java.sql.Timestamp(new java.util.Date().getTime());
			cache.put(idUser, timestamp.toString()+";"+pos);
		}
	

            	pstmt=con.prepareStatement("INSERT INTO datos (UserId, timestamp, latitud, longitud, velocidad, rumbo, altitud) VALUES (?, ?, ?, ?, ?, ?, ?);");
            	pstmt.setInt(1, idUser);
            	pstmt.setTimestamp(2, timestamp);
            	pstmt.setInt(3, latitud);
            	pstmt.setInt(4, longitud);
            	pstmt.setInt(5, velocidad);
            	pstmt.setInt(6, rumbo);
            	pstmt.setInt(7, altitud);
            	pstmt.executeUpdate();
	    }

 	  }	    
	  rs.close();
          pstmt.close();
          connMgr.freeConnection("mysql",con);

    } catch (ParseException e) {
	e.printStackTrace(); 
    } catch (NumberFormatException e) {
	e.printStackTrace(); 
    } catch (IOException e) {
	e.printStackTrace(); 
    } catch (GeneralSecurityException e) {
	e.printStackTrace(); 
    } catch (SQLException e) {
	e.printStackTrace();
    }

    if(con!=null)
        connMgr.freeConnection("mysql",con);
  }

  if(socket!=null)
	socket.close();
}
}
